/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package replic.console;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import replic.commons.Message;
import replic.commons.OutputMessage;

/**
 *
 * @author Leonardo Oliveira Moreira
 */
public class RepliCTerminalSocket extends RepliCTerminal {

    public RepliCTerminalSocket(int terminalId, File logFile, String databaseName, String replicHost, int replicPort) {
        super(terminalId, logFile, databaseName, replicHost, replicPort);
    }

    @Override
    public void run() {
        try {
            Socket socket = new Socket(replicHost, replicPort);
            OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Connection to RepliC Service");
            if (socket != null && !socket.isClosed()) {
                ObjectInputStream inputStream = null;
                ObjectOutputStream outputStream = null;
                boolean proceed = true;
                try {
                    outputStream = new ObjectOutputStream(socket.getOutputStream());
                    inputStream = new ObjectInputStream(socket.getInputStream());
                } catch (IOException ex) {
                    proceed = false;
                }
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Connected to RepliC Service");
                TransactionResult transactionResult = null;
                for (int i = 0; i < messageList.size(); i++) {
                    Message m = messageList.get(i);
                    m.setStartTime(System.currentTimeMillis());
                    if (proceed && socket != null && socket.isConnected()) {
                        if (transactionResult == null) {
                            transactionResult = new TransactionResult();
                            transactionResult.setStartTime(System.currentTimeMillis());
                        }
                        outputStream.writeObject(m);
                        try {
                            m = (Message) inputStream.readObject();
                            if (m.getSqlType() == Message.SQL_COMMIT || m.getSqlType() == Message.SQL_ROLLBACK) {
                                transactionResult.setEndTime(System.currentTimeMillis());
                                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Transaction Executed in " + (transactionResult.getEndTime() - transactionResult.getStartTime()) + " ms [" + (messageList.size() - (i + 1)) + " remaining operation(s)]");
                                transactionResults.add(transactionResult);
                                transactionResult = null;
                            }
                            else {
                                transactionResult.incrementOperationNumber();
                            }
                        } catch (ClassNotFoundException ex) {
                            OutputMessage.println(ex.getMessage());
                        }
                    }
                    m.setFinishTime(System.currentTimeMillis());
                }
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Closing Connection");
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + transactionResults.size() + " transaction(s) executed");
                socket.close();
                OutputMessage.println("RepliC Terminal " + terminalId + ": " + "Connection Closed");
            }
        } catch (IOException ex) {
            OutputMessage.println(ex.getMessage());
            executing = false;
            return;
        }
        executing = false;
    }

}